home *** CD-ROM | disk | FTP | other *** search
- // -------------------------------------------------------------------
- // Imaging.c
- //
- // -------------------------------------------------------------------
-
- #include "Structs.h"
-
- #include "Imaging.h"
-
- #include "DocumentADT.h"
- #include "DocumentHelpers.h"
-
- #include "ElementADT.h"
- #include "ElementHelpers.h"
-
- #include "WindowUtils.h"
-
- #include "Assertion.h"
-
- // -------------------------------------------------------------------
-
- static void SaveDrawingState (WindowPtr window, DrawingState *state);
- static void RestoreDrawingState (WindowPtr window, DrawingState *state);
-
- static void DrawEveryElement (DocumentReference document, ElementList list);
- static void DrawElement (ElementReference element);
-
- // -------------------------------------------------------------------
-
- void IMDraw(DocumentReference document)
- {
- GrafPtr currentPort;
-
- // for off-screen drawing
-
- CGrafPtr windowPort;
- GDHandle windowDevice;
- QDErr error;
- GWorldPtr offscreen = NULL;
- PixMapHandle offscreenPixMap = nil;
- Boolean success;
-
- Rect sourceRect;
- Rect destinationRect;
-
- BitMap * srcMap;
- BitMap * destMap;
-
- WindowPtr window = GetDocumentWindow(document);
- Rect portRect;
-
- RGBColor saveBackColor;
- RGBColor saveForeColor;
- RGBColor black = {0x0000, 0x0000, 0x0000};
- RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
-
- GetPort(¤tPort);
- SetPort(window);
-
- GetWindowPortRect(window, &portRect);
-
- GetGWorld(&windowPort, &windowDevice); // Save the window port
-
- // Make an offscreen GWorld
-
- error = NewGWorld(&offscreen, 0, &portRect, nil, nil, 0);
-
- if (error != noErr || offscreen == nil)
- {
- SysBeep(2);
- DebugStr("\pCan't create new GWorld.");
- goto CleanUp;
- }
-
- SetGWorld(offscreen, nil);
-
- offscreenPixMap = GetGWorldPixMap(offscreen);
-
- success = LockPixels(offscreenPixMap);
-
- if (!success)
- {
- SetGWorld(windowPort, windowDevice);
- SysBeep(2);
- DebugStr("\pCan't create LockPixels on new GWorld.");
- goto CleanUp;
- }
-
- PenNormal();
- RGBForeColor(&black);
- RGBBackColor(&white);
- EraseRect(&offscreen->portRect);
-
- DrawEveryElement(document, GetDocumentElementList(document));
-
- // Go back to the window port
-
- SetGWorld(windowPort, windowDevice);
-
- sourceRect = offscreen->portRect;
- destinationRect = portRect;
-
- srcMap = (BitMap *) *GetGWorldPixMap(offscreen);
- destMap = (BitMap *) &(((GrafPtr) window)->portBits);
-
- GetForeColor(&saveForeColor);
- GetBackColor(&saveBackColor);
-
- RGBForeColor(&black);
- RGBBackColor(&white);
-
- CopyBits(srcMap, destMap, &sourceRect, &destinationRect, srcCopy, nil);
-
- if (QDError() != noErr)
- {
- SysBeep(2);
- DebugStr("\pCopyBits() returned and error.");
-
- }
-
- RGBBackColor(&saveBackColor);
- RGBForeColor(&saveForeColor);
-
- CleanUp:
-
- if (offscreenPixMap != nil)
- UnlockPixels(offscreenPixMap);
-
- if (offscreen != NULL)
- DisposeGWorld(offscreen);
-
- SetPort(currentPort);
- }
-
- // -------------------------------------------------------------------
-
- void IMDelete(DocumentReference document, ElementReference element)
- {
- DestroyElement(element);
- IMDraw(document);
- }
-
- // -------------------------------------------------------------------
-
- void ResizeElementData(DocumentReference document, ElementReference element, Rect newBounds)
- {
- Rect oldBounds;
-
- oldBounds = GetElementBoundingBox(element);
-
- // --- resize depending on shape -----------------------------------------
-
- switch (GetElementType(element))
- {
- case kQDLine:
- ResizeOpenEndedObject(document, element, newBounds);
- break;
-
- case kQDRect:
- case kQDRoundRect:
- case kQDOval:
- ResizeClosedObject(document, element, newBounds);
- break;
-
- case kQDPolygon:
- ResizePolygon(document, element, newBounds);
- break;
-
- case kGroup:
- ResizeGroup(document, element, newBounds);
- break;
-
- default:
- Assert(kAssertAlways, "Resizing is disabled for this type of object.");
- break;
- }
- }
-
- // -----------------------------------------------------------------------------------------
-
- void ResizeOpenEndedObject(DocumentReference document, ElementReference element, Rect newBounds)
- {
- #pragma unused (document, element, newBounds)
-
- }
-
-
- // -----------------------------------------------------------------------------------------
-
- void ResizeClosedObject(DocumentReference document, ElementReference element, Rect newBounds)
- {
- #pragma unused (document)
-
- SetElementBoundingBox(element, newBounds);
- }
-
-
- // -----------------------------------------------------------------------------------------
-
- void ResizePolygon(DocumentReference document, ElementReference element, Rect newBounds)
- {
- #pragma unused (document, element, newBounds)
-
- }
-
-
- // -----------------------------------------------------------------------------------------
-
- void ResizeGroup(DocumentReference document, ElementReference element, Rect newBounds)
- {
- #pragma unused (document, element, newBounds)
-
- }
-
-
- // -----------------------------------------------------------------------------------------
-
- void MoveElementData(DocumentReference document, ElementReference element, short newTop, short newLeft)
- {
- Rect elementRect;
- short deltaH;
- short deltaV;
-
- elementRect = GetElementBoundingBox(element);
-
- deltaV = newTop - elementRect.top;
- deltaH = newLeft - elementRect.left;
-
- OffsetElementData(document, element, deltaH, deltaV);
- }
-
- // -----------------------------------------------------------------------------------------
-
- void OffsetElementData(DocumentReference document, ElementReference element, short deltaH, short deltaV)
- {
- ElementReference subElement;
- Rect elementRect;
- PolyHandle polygon;
- Point begin;
- Point end;
-
- if (deltaH || deltaV)
- {
- // --- go recursive if we have to ----------------------------------------
-
- if (GetElementType(element) == kGroup)
- for (subElement = GetFirstSubElement(element); subElement != nil; subElement = GetNextElement(subElement))
- OffsetElementData(document, subElement, deltaH, deltaV);
-
- // --- offset bounding box -----------------------------------------------
-
- elementRect = GetElementBoundingBox(element); // extract current element rectangle
- OffsetRect(&elementRect, deltaH, deltaV); // offset for new position
- SetElementBoundingBox(element, elementRect); // set new bounding box
-
- // --- offset dependent data ---------------------------------------------
-
- switch (GetElementType(element))
- {
- case kQDLine:
- begin = GetElementLineBeginPoint(element);
- end = GetElementLineEndPoint(element);
-
- begin.h += deltaH;
- end.h += deltaH;
- begin.v += deltaV;
- end.v += deltaV;
-
- SetElementLineBeginPoint(element, begin);
- SetElementLineEndPoint(element, end);
-
- break;
-
- case kQDPolygon:
- polygon = GetElementPolygon(element);
- if (polygon != nil)
- {
- OffsetPoly(polygon, deltaH, deltaV);
- }
- break;
-
- default:
- // do nothing special for other types
- break;
- }
- }
- }
-
- // -----------------------------------------------------------------------------------------
-
- static void DrawEveryElement(DocumentReference document, ElementList list)
- {
- ElementReference element;
-
- for (element = GetFirstElement(list); element != nil; element = GetNextElement(element))
- {
- if (GetElementType(element) != kGroup)
- {
- DrawElement(element);
- }
- else
- {
- DrawEveryElement(document, GetElementSubElementList(element));
- }
- }
- }
-
- // -----------------------------------------------------------------------------------------
-
- static void DrawElement(ElementReference element)
- {
- ElementType elementType;
- Rect elementBounds;
- Point p1;
- Point p2;
-
- RGBColor strokeColor;
- RGBColor fillColor;
- short penWidth;
- short penHeight;
-
- strokeColor = GetElementStrokeColor(element);
- fillColor = GetElementFillColor(element);
- penWidth = GetElementStrokePenWidth(element);
- penHeight = GetElementStrokePenHeight(element);
-
- elementType = GetElementType(element);
- elementBounds = GetElementBoundingBox(element);
-
- PenSize(penWidth, penHeight);
-
- switch (elementType)
- {
- case kQDLine:
- RGBForeColor(&strokeColor);
- p1 = GetElementLineBeginPoint(element);
- p2 = GetElementLineEndPoint(element);
- MoveTo(p1.h, p1.v);
- LineTo(p2.h, p2.v);
- break;
-
- case kQDRect:
- RGBForeColor(&fillColor);
- FillRect(&elementBounds, &qd.black);
-
- RGBForeColor(&strokeColor);
- FrameRect(&elementBounds);
- break;
-
- case kQDOval:
- RGBForeColor(&fillColor);
- FillOval(&elementBounds, &qd.black);
-
- RGBForeColor(&strokeColor);
- FrameOval(&elementBounds);
- break;
-
- case kQDPolygon:
- RGBForeColor(&fillColor);
- FillPoly(GetElementPolygon(element), &qd.black);
-
- RGBForeColor(&strokeColor);
- FramePoly(GetElementPolygon(element));
- break;
-
- case kQDRoundRect:
- p1 = GetElementRoundRectOvalSize(element);
-
- RGBForeColor(&fillColor);
- FillRoundRect(&elementBounds, p1.h, p1.v, &qd.black);
-
- RGBForeColor(&strokeColor);
- FrameRoundRect(&elementBounds, p1.h, p1.v);;
- break;
-
- default:
- RGBForeColor(&fillColor);
- FillRect(&elementBounds, &qd.black);
-
- RGBForeColor(&strokeColor);
- FrameRect(&elementBounds);
- break;
- }
-
- }
-
- // -----------------------------------------------------------------------------------------
-
- static void SaveDrawingState(WindowPtr window, DrawingState *state)
- {
- GrafPtr curPort;
-
- GetPort(&curPort);
- SetPort(window);
-
- GetPenState(&(state->penState));
-
- GetForeColor(&(state->foreColor));
- GetBackColor(&(state->backColor));
-
- SetPort(curPort);
- }
-
- // -----------------------------------------------------------------------------------------
-
- static void RestoreDrawingState(WindowPtr window, DrawingState *state)
- {
- GrafPtr curPort;
-
- GetPort(&curPort);
- SetPort(window);
-
- SetPenState(&(state->penState));
-
- RGBForeColor(&(state->foreColor));
- RGBBackColor(&(state->backColor));
-
- SetPort(curPort);
- }
-
- // -----------------------------------------------------------------------------------------
-
-
-
-